<?php

include_once("interface.php");

class Net extends Data
{
    //defines the filename where the data is stored, could be multiple files.
    private $netpath = "/etc/sysconfig/network-scripts/";
    //private $netpath = "/tmp/network-scripts/";
    public $title = "Interface";
    public $module = "net";

    public $data = array(   "hostname" => "", 
                            "gateway" => "",
                            "devices" => array(
                            ),
                            "interfaces" => array()
                        );

    //defines the interface struct as example, not used, since its a straight array
    private $int = array(
                    "mode" => "",
                    "device" => "",
                    "ipaddr" => "",
                    "netmask" => "",
                    "network" => "",
                    "broadcast" => "",
                    "bootproto" => "",
                    "hwaddr" => "",
                    "onboot" => "",
                    "ports" => array()
                    );


    public function __construct() {
        $this->getRealInterfaces();
    }

    private function getHostname() {
        $fn = "/etc/sysconfig/network";
        $filearray = file($fn);
        if ( $filearray == false ) {
            return false;
        }
        foreach ( $filearray as $arrval ) {
            $val = trim($arrval);
            if ( preg_match("/^#/", $val) ) {
                continue;
            }
            if ( preg_match("/HOSTNAME/", $val) ) {
                list($key, $value) = split('=', $val);
                return $value;
            }
        }
    }

    private function getRealInterfaces() {
        $i = 0;
        $dn = "/sys/class/net";
        $filearray = scandir($dn);
        if ( $filearray == false ) {
            return false;
        }
        foreach ( $filearray as $arrval ) {
            if ( preg_match("/eth[0-9]/", $arrval) ) {
                array_push($this->data["devices"], trim($arrval));
            }
        }
    }

    private function getGateway() {
        $val = `netstat -rn | grep "^0.0.0.0" | awk '{printf("%s", $2) }'`;
        return $val;
    }

    private function getDHCPInfo($dev) {
        $info = array();
        $info[0] = `ifconfig $dev | grep 'inet addr' | awk '{ printf("%s", $2) }' | awk -F':' '{ printf("%s", $2) }'`;
        $info[1] = `ifconfig $dev | grep 'inet addr' | awk '{ printf("%s", $4) }' | awk -F':' '{ printf("%s", $2) }'`;
        $info[2] = `netstat -rn | grep "^0.0.0.0" | awk '{printf("%s", $2) }'`;
        return $info;
    }

    //read the data from files and return a complete object
    function readDataFromSystem() {
        $dn = $this->netpath;
        $filearray = scandir($dn);

        foreach ($filearray as $file) {
            if ( !preg_match("/ifcfg-bond[0-9]/", $file) && !preg_match("/ifcfg-eth[0-9]/", $file) ) {
                continue;
            }
            $fn = $this->netpath.$file;
            if(!file_exists($fn)) {
                continue;
            }
            $filearray = file($fn);

            if ( $filearray == false ) {
                continue; 
            }

            $int = array();
            foreach ( $filearray as $arrval ) {
                $val = trim($arrval);
                if ( preg_match("/^#/", $val) ) {
                    continue;
                }
                list($key, $value) = split('=', $val);

                switch($key) {
                case "MODE":
                    $int["mode"] = $value;
                    break;
                case "DEVICE":
                    $int["device"] = $value;
                    break;
                case "IPADDR":
                    $int["ipaddr"] = $value;
                    break;
                case "NETMASK":
                    $int["netmask"] = $value;
                    break;
                case "NETWORK":
                    $int["network"] = $value;
                    break;
                case "BROADCAST":
                    $int["broadcast"] = $value;
                    break;
                case "BOOTPROTO":
                    $int["bootproto"] = $value;
                    if ($value == "dhcp") {
                        list($int["ipaddr"], $int["netmask"], $this->data["gateway"]) = $this->getDHCPInfo($int["device"]);
                    }
                    break;
                case "HWADDR":
                    $int["hwaddr"] = $value;
                    break;
                case "ONBOOT":
                    $int["onboot"] = $value;
                    break;
                case "PORTS":
                    $int["ports"] = split(",", $value);
                    break;
                case "HOSTNAME":
                    $this->data["hostname"] = $value;
                    break;
                case "GATEWAY":
                    $this->data["gateway"] = $value;
                    break;
                default:
                    error_log("net.php readDataFromSystem: Unknown key->val Found $val--");
                }
            }

            if ( $int["mode"] == "bonding" && preg_match("/eth/", $int["device"]) ) {
                //dont add slaves when in bonding
                continue;
            }

            array_push($this->data["interfaces"], $int);

            if ( $this->data["hostname"] == "" ) {
                $this->data["hostname"] = $this->getHostname();
            }
            if ( $this->data["gateway"] == "" ) {
                $this->data["gateway"] = $this->getGateway();
            }

            $this->data["forwarding"] == `cat /proc/sys/net/ipv4/ip_forward`;
        }
        return $this->data;
    }

    //write the obj to the file
    function commitDataToSystem($obj) {

        $ret;
        $retstr = "Successfully set the networking.";

        $path = $this->netpath."ifcfg-eth*";
        system("rm -f $path");
        $path = $this->netpath."ifcfg-bond*";
        system("rm -f $path");

        foreach ($obj["interfaces"] as $int) {
            $device = $int["device"];

            $path = $this->netpath."ifcfg-";

            $fn = $path.$device;
            $tmp = "#".$fn."\n";
            $tmp = $tmp."MODE=".$int["mode"]."\n";
            $tmp = $tmp."DEVICE=".$device."\n";
            if ( $int["bootproto"] == "dhcp") {
                $tmp = $tmp."BOOTPROTO=".$int["bootproto"]."\n";
            }
            else {
                $tmp = $tmp."BOOTPROTO=static\n";
                $tmp = $tmp."IPADDR=".$int["ipaddr"]."\n";
                $tmp = $tmp."NETMASK=".$int["netmask"]."\n";
            }
            $tmp = $tmp."ONBOOT=yes\n";
        
            $addr_path = "/sys/class/net/".$device."/address";

            $hwaddr = `cat $addr_path`;
            $tmp = $tmp."HWADDR=".trim($hwaddr)."\n";

            //bonding or standalone
            if ( $int["mode"] == "bonding") {
                $tmp = $tmp."PORTS=".$int["ports"][0].",".$int['ports'][1]."\n";
                $slave1  = $path.$int["ports"][0];
                $slave2  = $path.$int["ports"][1];
                $slave_tmp = $slave_tmp."MASTER=".$device."\nONBOOT=yes\nUSERCTL=no\nBOOTPROTO=none\nSLAVE=yes\n";
                $slave1_tmp = "#".$slave1."\n"."DEVICE=".$int["ports"][0]."\n".$slave_tmp;
                $slave2_tmp = "#".$slave2."\n"."DEVICE=".$int["ports"][1]."\n".$slave_tmp;
                $s1_fd = fopen($slave1, "w");
                fwrite($s1_fd, $slave1_tmp);
                fclose($s1_fd);
                $s2_fd = fopen($slave2, "w");
                fwrite($s2_fd, $slave2_tmp);
                fclose($s2_fd);
            }
            else {
                $tmp = $tmp."PORTS=\n";
            }

            $fd = fopen($fn, "w");
            $ret = fwrite($fd, $tmp);
            if($ret == false) {
                $retstr = "Failed to set networking. Write to file failed.";
            }

            fclose($fd);

            exec("/sbin/modprobe bond0", $out, $ret);
            if($ret != 0) {
                $retstr = "Failed to add bonding module.";
            }
        }

        //gateway
        $tmp=$obj['gateway'];
        $fd = fopen("/etc/sysconfig/network", "a");
        $ret = fwrite($fd, "GATEWAY=".$tmp."\n");
        if($ret == false) {
            $retstr = "Failed to set gateway. Write to file failed.";
        }
        fclose($fd);

        //hostname
        $tmp=$obj['hostname'];
        $fd = fopen("/etc/hostname", "w");
        $ret = fwrite($fd, $tmp);
        if($ret == false) {
            $retstr = "Failed to set hostname. Write to file failed.";
        }
        fclose($fd);

        //forwarding
        $out = array();
        if($obj['forwarding'] == 1) {
            $cmd = "sed -i -r 's/^net.ipv4.ip_forward.*/net.ipv4.ip_forward=1/' /etc/sysctl.conf";
        }
        else {
            $cmd = "sed -i -r 's/^net.ipv4.ip_forward.*/net.ipv4.ip_forward=0/' /etc/sysctl.conf";
        }
        exec($cmd, $out, $ret);
        if($ret != 0) {
            $retstr = "Fail to set forwarding";
            return $retstr;
        }

        exec("/etc/init.d/network restart", $out, $ret);
        if($ret != 0) {
            $retstr = "Failed to set networking. network restart failed.";
        }

        return $retstr;
    }

    function printModuleScript() {
        return file_get_contents("net.js");
    }

    function printModuleHTML() {
        return file_get_contents("net.html");
    }
}

?>
